package com.atguigu.gmall.activity.controller;

import com.atguigu.gmall.activity.service.SecKillGoodsService;
import com.atguigu.gmall.activity.util.CacheHelper;
import com.atguigu.gmall.constant.MqConst;
import com.atguigu.gmall.constant.RedisConst;
import com.atguigu.gmall.model.activity.OrderRecode;
import com.atguigu.gmall.model.activity.SeckillGoods;
import com.atguigu.gmall.model.activity.UserRecode;
import com.atguigu.gmall.model.order.OrderDetail;
import com.atguigu.gmall.model.order.OrderInfo;
import com.atguigu.gmall.model.user.UserAddress;
import com.atguigu.gmall.order.client.OrderFeignClient;
import com.atguigu.gmall.result.Result;
import com.atguigu.gmall.result.ResultCodeEnum;
import com.atguigu.gmall.service.RabbitService;
import com.atguigu.gmall.user.client.UserFeignClient;
import com.atguigu.gmall.util.AuthContextHolder;
import com.atguigu.gmall.util.DateUtil;
import com.atguigu.gmall.util.MD5;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import java.util.*;

@RestController
@RequestMapping("/api/activity/seckill")
@SuppressWarnings("all")
public class SeckillGoodsApiController {

    @Autowired
    private SecKillGoodsService secKillGoodsService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RabbitService rabbitService;

    @Autowired
    private UserFeignClient userFeignClient;

    @Autowired
    private OrderFeignClient orderFeignClient;

    /**
     * 保存秒杀订单
     * /api/activity/seckill/auth/submitOrder
     * @param orderInfo
     * @param request
     * @return
     */
    @PostMapping("/auth/submitOrder")
    public Result submitOrder(@RequestBody OrderInfo orderInfo,HttpServletRequest request) {
        // 获取用户id
        String userId = AuthContextHolder.getUserId(request);
        // 设置user
        orderInfo.setUserId(Long.parseLong(userId));
        Result result = orderFeignClient.submitOrderSeckill(orderInfo);
        // 获取orderId
        Object orderId = result.getData();
        // 判断
        if (orderId==null) {
            return result.fail().message("下单失败，重新下单");
        }
        // 处理临时订单
        this.redisTemplate.boundHashOps(RedisConst.SECKILL_ORDERS).delete(userId);
        // 添加一个用户的订单记录
        this.redisTemplate.boundHashOps(RedisConst.SECKILL_ORDERS_USERS).put(userId,orderId);

        return Result.ok(orderId);
    }

    /**
     * 秒杀下单确认
     * /api/activity/seckill/auth/trade
     * @return
     */
    @GetMapping("/auth/trade")
    public Result trade(HttpServletRequest request) {
        // 查询送货清单
        String userId = AuthContextHolder.getUserId(request);
        // 获取
        OrderRecode orderRecode = (OrderRecode) this.redisTemplate.boundHashOps(RedisConst.SECKILL_ORDERS).get(userId);
        // 判断是否有订单
        if (orderRecode == null) {
            return Result.fail().message("非法请求！");
        }

        // 获取秒杀商品
        SeckillGoods seckillGoods = orderRecode.getSeckillGoods();
        // 转换数据类型
        List<OrderDetail> orderDetailList = new ArrayList<>();
        // 创建订单详情对象
        OrderDetail orderDetail = new OrderDetail();
        orderDetail.setSkuId(seckillGoods.getSkuId());
        orderDetail.setSkuName(seckillGoods.getSkuName());
        orderDetail.setImgUrl(seckillGoods.getSkuDefaultImg());
        orderDetail.setOrderPrice(seckillGoods.getCostPrice());
        orderDetail.setSkuNum(1);
        orderDetailList.add(orderDetail);

        // 计算总金额
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setOrderDetailList(orderDetailList);
        // 计算
        orderInfo.sumTotalAmount();

        // 查询用户地址列表
        List<UserAddress> userAddressList = userFeignClient.findUserAddressListByUserId(Long.parseLong(userId));

        // 存储数据
        Map<String,Object> resultMap = new HashMap<>();
        resultMap.put("detailArrayList",orderDetailList);
        resultMap.put("userAddressList",userAddressList);
        resultMap.put("totalNum",1);
        resultMap.put("totalAmount",orderInfo.getTotalAmount());

        return Result.ok(resultMap);
    }

    /**
     * 查询秒杀抢购状态
     * /api/activity/seckill/auth/checkOrder/{skuId}
     * @param skuId
     * @return
     */
    @GetMapping("/auth/checkOrder/{skuId}")
    public Result checkOrder(@PathVariable Long skuId,HttpServletRequest request) {
        // 获取用户id
        String userId = AuthContextHolder.getUserId(request);

        return this.secKillGoodsService.checkOrder(skuId,userId);
    }

    /**
     * 秒杀下单排队
     * /api/activity/seckill/auth/seckillOrder/{skuId}
     * @param skuId
     * @return
     */
    @PostMapping("/auth/seckillOrder/{skuId}")
    public Result seckillOrder(@PathVariable Long skuId,HttpServletRequest request) {
        // 校验下单码
        String skuIdStr = request.getParameter("skuIdStr");
        // 获取用户id
        String userId = AuthContextHolder.getUserId(request);
        if (MD5.encrypt(userId).equals(skuIdStr)) {
            // 校验状态位 key:skuId 23  value:状态位 1或0
            String status = (String) CacheHelper.get(skuId.toString());
            if (StringUtils.isEmpty(status)) {
                return Result.build(null, ResultCodeEnum.SECKILL_ILLEGAL);
            }

            // 判断状态值
            if ("0".equals(status)) {
                return Result.build(null, ResultCodeEnum.SECKILL_FINISH);
            } else {
                // 生成抢单信息对象
                UserRecode userRecode = new UserRecode();
                userRecode.setSkuId(skuId);
                userRecode.setUserId(userId);

                // 发送消息排队
                this.rabbitService.sendMessage(
                        MqConst.EXCHANGE_DIRECT_SECKILL_USER,
                        MqConst.ROUTING_SECKILL_USER,
                        userRecode);

                return Result.ok();
            }
        }

        return Result.build(null, ResultCodeEnum.SECKILL_ILLEGAL);
    }

    /**
     * 获取抢单码
     * /api/activity/seckill/auth/getSeckillSkuIdStr/{skuId}
     * @param skuId
     * @return
     */
    @GetMapping("/auth/getSeckillSkuIdStr/{skuId}")
    public Result getSeckillSkuIdStr(@PathVariable Long skuId, HttpServletRequest request) {
        // 获取用户id
        String userId = AuthContextHolder.getUserId(request);

        SeckillGoods seckillGoods = (SeckillGoods) this.redisTemplate.boundHashOps(RedisConst.SECKILL_GOODS).get(skuId.toString());
        // 判断
        if (seckillGoods != null) {
            // 获取当前时间
            Date curDate = new Date();
            // 判断
            if (DateUtil.dateCompare(seckillGoods.getStartTime(),curDate) &&
                    DateUtil.dateCompare(curDate,seckillGoods.getEndTime())) {
                // 生成抢单码
                // 此时已经登录了，因为访问的是auth
                String encrypt = MD5.encrypt(userId);
                return Result.ok(encrypt);
            }
        }
        return Result.fail("获取抢单码失败!");
    }

    /**
     * 根据skuId获取数据
     * 获取秒杀商品详情
     * /api/activity/seckill/getSeckillGoods/{skuId}
     * @param skuId
     * @return
     */
    @GetMapping("/getSeckillGoods/{skuId}")
    public Result getSeckillGoods(@PathVariable Long skuId) {
        SeckillGoods seckillGoods = secKillGoodsService.getSeckillGoods(skuId);
        return Result.ok(seckillGoods);
    }

    /**
     * /api/activity/seckill/findAll
     * 查询秒杀列表
     * @return
     */
    @GetMapping("/findAll")
    public Result findAll() {
        List<SeckillGoods> seckillGoodsList = secKillGoodsService.findAll();
        return Result.ok(seckillGoodsList);
    }
}
